 package ru.pm.dashboard.helper;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 
 import java.io.Serializable;
 import java.util.Comparator;
 
 /**
  * Класс предназначен для расчёта статистических показателей "на лету" без необходимости сохранять значения в списке.
  */
 @RequiredArgsConstructor
 @Getter
 public class Stats implements Serializable, Comparable<Stats> {
 
     private static final long serialVersionUID = 5189576175560182641L;
 
     private final String x1;
     private final String x2;
 
     private long mN = 0L;
     private double mM = 0.0;
     private double mS = 0.0;
 
     private double min = Double.POSITIVE_INFINITY;
     private double max = Double.NEGATIVE_INFINITY;
     private double sum = 0.0;
 
     /**
      * Добавить очередное значение из исходных данных
      *
      * @param s Значение
      */
     public void push(String s) {
         ++mN;
         double x;
         try {
             x = Double.parseDouble(s);
         } catch (Exception e) {
             return;
         }
         double nextM = mM + (x - mM) / mN;
         mS += (x - mM) * (x - nextM);
         mM = nextM;
 
         sum += x;
 
         if (x < min) {
             min = x;
         }
 
         if (x > max) {
             max = x;
         }
     }
 
     public long numSamples() {
         return mN;
     }
 
     public double mean() {
         return mM;
     }
 
     public double variance() {
         return mN > 1 ? mS / mN : 0.0;
     }
 
     public double varianceUnbiased() {
         return mN > 1 ? mS / (mN - 1) : 0.0;
     }
 
     public double standardDeviation() {
         return Math.sqrt(variance());
     }
 
     public double standardDeviationUnbiased() {
         return Math.sqrt(varianceUnbiased());
     }
 
     public double min() {
         return min;
     }
 
     public double max() {
         return max;
     }
 
     public double sum() {
         return sum;
     }
 
     private static final Comparator<String> NULL_SAFE_STRING_COMPARATOR = Comparator.nullsFirst(String::compareTo);
 
     @Override
     public int compareTo(Stats stats) {
         return Comparator.comparing(Stats::getX2, NULL_SAFE_STRING_COMPARATOR)
                 .thenComparing(Stats::getX1)
                 .compare(this, stats);
     }
 }